// __DefBitFieldType TypeName<N> 定义位宽为N的BitField类型 ，
// ISA 描述中的__Encoding段的所有变量都必须是某个BitFieldType，且位宽必须匹配

// BitFieldType可以看成是固定位宽的枚举类型
// 正确性检查：1. 枚举成员/值有无重复；2. 枚举值在位宽范围内；
// TODO：理论上所有枚举值必须不同，但是否需要支持别名？比如T=True=true？
//

__DefBitFieldType Optype<8>
    // FALU
    FADD = 0x0;
    FMUL;
    FFMA;
    FMNMX;
    FSETP;
    FSET;
    FSEL;
    FCHK;

    //HALU
    HADD2;
    HMUL2;
    HFMA2;
    HMNMX2;
    HSETP2;
    HSET2;

    //DALU
    DADD;
    DMUL;
    DFMA;
    DMNMX;
    DSETP;

    F2F_64;
    F2I_64;
    I2F_64;
    FRND_64;

    // IALU
    IADD;
    IMAD;
    IMAD_WIDE;
    IDP2A;
    IDP4A;
    IMUL;
    LEA;
    IABS;
    IMNMX;
    P2R;
    R2P;
    ISETP;
    ISET;
    SEL;
    LOP3;
    PLOP3;
    SHF;
    MOV;
    PRMT;
    I2I;
    I2IP;
    R2UR;
    SETGPR;
    GETGPR;

    MOVM; // ???

    //
    F2F;
    F2I;
    I2F;
    FRND;
    F2IP;
    // I2FP;
    F2FP;

    // UDP
    UIADD;
    UIMAD;
    UIMAD_WIDE;
    UIMUL;
    ULEA;
    UIABS;
    UIMNMX;
    UP2UR;
    UR2UP;
    UISETP;
    USEL;
    ULOP3;
    UPLOP3;
    USHF;
    UMOV;
    UPRMT;
    UPOPC;
    UFLO;
    UBREV;
    UBMSK;
    USGXT;
    UF2FP; // TODO???
    SETUGPR;
    GETUGPR;

    //* Multi Function Unit
    MUFU;
    POPC;
    FLO;
    BREV;
    BMSK;
    SGXT;

    // BRU
    BRA;
    BRX;
    CALL;
    RET;
    EXIT;
    LEPC;
    BMOV;
    BSSY;
    BSYNC;
    YIELD;
    BREAK;
    WARPSYNC;
    NANOSLEEP;
    TRAP;
    RTT;
    SYSCALL;

    // LSU
    LDC;
    ULDC;

    LDG;
    LDS;
    LDSM;
    LDL;
    LD;

    STG;
    STS;
    STSM;
    STL;
    ST;

    LDGSTS;
    LDSSTG;

    ATOMG;
    ATOMS;
    ATOM;
    RED;

    CCTL;
    CCTLL;
    LDGDEPBAR;
    MEMBAR;
    ERRBAR;
    QSPC;

    //
    SHFL;
    VOTE;
    VOTEU;
    MATCH;
    REDUX;
    REDUXU;
    ELECT;
    ELECTU;

    // MMA
    HMMA;
    HMMA_SP;
    IMMA;
    IMMA_SP;
    BMMA;
    QMMA;
    QMMA_SP;
    OMMA; // ???

    // BCU
    BAR;
    BAR_RED;
    B2R;
    B2R_RESULT;
    R2B;

    // MISC
    S2R;
    S2UR;
    CS2R;
    SETREG;
    GETREG;
    PMTRIG;
    SWITCH;

    // IB
    DEPBAR;
    IBBAR;
    NOP;

// Src Type, usually only for ALU?
// TODO:
__DefBitFieldType SType<4>
    X = 0x0;  // No src/Special treatment/Optype determined
    R = 0x1;           // SrcA
    U;
    I;
    C;
    RR = 0x5;          // SrcA + SrcB
    RU;
    RI;
    RC;
    RRR = 0x9;         // SrcA + SrcB + SrcC
    RRU;
    RUR;
    RRI;
    RIR;
    RRC;
    RCR;
    // TODO ： SrcE ?

__DefBitFieldType USType<4>
    X = 0x0;  // No src/Special treatment/Optype determined
    U = 0x2;  // SrcB
    I;
    C;
    UU = 0x6;    // SrcA + SrcB
    UI;
    UC;
    UUU = 0xa;   // SrcA + SrcB + SrcC
    UUI;
    UIU;
    UUC;
    UCU;
    // TODO ： SrcE ?

// TODO:
__DefBitFieldType IOType<4>
    X = 0x0;
    R;
    U;
    I;
    P;
    UP;

__DefBitFieldType Pred<3>
    P0;
    P1;
    P2;
    P3;
    P4;
    P5;
    P6;
    PT;

__DefBitFieldType Reg<8>
    R0;
    R1;
    R2;
    R3;
    R4;
    R5;
    R6;
    R7;
    R8;
    R9;
    R10;
    R11;
    R12;
    R13;
    R14;
    R15;
    R16;
    R17;
    R18;
    R19;
    R20;
    R21;
    R22;
    R23;
    R24;
    R25;
    R26;
    R27;
    R28;
    R29;
    R30;
    R31;
    R32;
    R33;
    R34;
    R35;
    R36;
    R37;
    R38;
    R39;
    R40;
    R41;
    R42;
    R43;
    R44;
    R45;
    R46;
    R47;
    R48;
    R49;
    R50;
    R51;
    R52;
    R53;
    R54;
    R55;
    R56;
    R57;
    R58;
    R59;
    R60;
    R61;
    R62;
    R63;
    R64;
    R65;
    R66;
    R67;
    R68;
    R69;
    R70;
    R71;
    R72;
    R73;
    R74;
    R75;
    R76;
    R77;
    R78;
    R79;
    R80;
    R81;
    R82;
    R83;
    R84;
    R85;
    R86;
    R87;
    R88;
    R89;
    R90;
    R91;
    R92;
    R93;
    R94;
    R95;
    R96;
    R97;
    R98;
    R99;
    R100;
    R101;
    R102;
    R103;
    R104;
    R105;
    R106;
    R107;
    R108;
    R109;
    R110;
    R111;
    R112;
    R113;
    R114;
    R115;
    R116;
    R117;
    R118;
    R119;
    R120;
    R121;
    R122;
    R123;
    R124;
    R125;
    R126;
    R127;
    R128;
    R129;
    R130;
    R131;
    R132;
    R133;
    R134;
    R135;
    R136;
    R137;
    R138;
    R139;
    R140;
    R141;
    R142;
    R143;
    R144;
    R145;
    R146;
    R147;
    R148;
    R149;
    R150;
    R151;
    R152;
    R153;
    R154;
    R155;
    R156;
    R157;
    R158;
    R159;
    R160;
    R161;
    R162;
    R163;
    R164;
    R165;
    R166;
    R167;
    R168;
    R169;
    R170;
    R171;
    R172;
    R173;
    R174;
    R175;
    R176;
    R177;
    R178;
    R179;
    R180;
    R181;
    R182;
    R183;
    R184;
    R185;
    R186;
    R187;
    R188;
    R189;
    R190;
    R191;
    R192;
    R193;
    R194;
    R195;
    R196;
    R197;
    R198;
    R199;
    R200;
    R201;
    R202;
    R203;
    R204;
    R205;
    R206;
    R207;
    R208;
    R209;
    R210;
    R211;
    R212;
    R213;
    R214;
    R215;
    R216;
    R217;
    R218;
    R219;
    R220;
    R221;
    R222;
    R223;
    R224;
    R225;
    R226;
    R227;
    R228;
    R229;
    R230;
    R231;
    R232;
    R233;
    R234;
    R235;
    R236;
    R237;
    R238;
    R239;
    R240;
    R241;
    R242;
    R243;
    R244;
    R245;
    R246;
    R247;
    R248;
    R249;
    R250;
    R251;
    R252;
    R253;
    R254;
    RZ;

__DefBitFieldType UPred<3>
    UP0;
    UP1;
    UP2;
    UP3;
    UP4;
    UP5;
    UP6;
    UPT;

__DefBitFieldType UReg<6>
    UR0;
    UR1;
    UR2;
    UR3;
    UR4;
    UR5;
    UR6;
    UR7;
    UR8;
    UR9;
    UR10;
    UR11;
    UR12;
    UR13;
    UR14;
    UR15;
    UR16;
    UR17;
    UR18;
    UR19;
    UR20;
    UR21;
    UR22;
    UR23;
    UR24;
    UR25;
    UR26;
    UR27;
    UR28;
    UR29;
    UR30;
    UR31;
    UR32;
    UR33;
    UR34;
    UR35;
    UR36;
    UR37;
    UR38;
    UR39;
    UR40;
    UR41;
    UR42;
    UR43;
    UR44;
    UR45;
    UR46;
    UR47;
    UR48;
    UR49;
    UR50;
    UR51;
    UR52;
    UR53;
    UR54;
    UR55;
    UR56;
    UR57;
    UR58;
    UR59;
    UR60;
    UR61;
    UR62;
    URZ;

__DefBitFieldType PModi<1> // Only for "!"
    False = 0x0;
    True = 0x1;

__DefBitFieldType SignModi<1> // Only for "-, ||, ~"
    False = 0x0;
    True = 0x1;


__DefBitFieldType HSel<1>
    H0 = 0x0;
    H1 = 0x1;

__DefBitFieldType HSel2<2>
    H1_H0 = 0x0;
    H0_H0 = 0x1;
    H1_H1 = 0x2;
    F32   = 0x3; // TODO: ???

__DefBitFieldType FPFtz<1>
    NoFTZ = 0x0;
    FTZ   = 0x1;

__DefBitFieldType FPSat<1>
    NoSAT = 0x0;
    SAT   = 0x1;

__DefBitFieldType FPRound<2>
    RN = 0x0;
    RP = 0x1;
    RM = 0x2;
    RZ = 0x3;

__DefBitFieldType FMULScale<3>
    NoScale;
    D2;
    D4;
    D8;
    M2;
    M4;
    M8;

__DefBitFieldType NAN<1>
    NoNAN;
    NAN;

__DefBitFieldType RELU<1>
    NoRELU;
    RELU;

// ??? TODO:
__DefBitFieldType XORSIGN<1>
    NoXORSIGN;
    XORSIGN;

__DefBitFieldType HFmtV2<1>
    F16_V2  = 0x0;
    BF16_V2 = 0x1;

__DefBitFieldType MUFUOp<3>
    COS=0x0;
    SIN=0x1;
    EX2=0x2;
    LG2=0x3;
    RCP=0x4;
    RSQ=0x5;
    SQRT=0x6;
    TANH=0x7;

__DefBitFieldType MUFUDType<3>
    F32;
    F64H;
    F16_V2;
    BF16_V2;
    F16;
    BF16;

__DefBitFieldType ICMPOp<3>
    EQ;
    NE;
    LT;
    LE;
    GT;
    GE;

__DefBitFieldType LOPOp<2>
    AND;
    OR;
    XOR;

//* Extended precision int cmp
__DefBitFieldType CMPEX<1>
    NoEX;
    EX;

__DefBitFieldType FCMPOp<4>
    EQ;
    NE;
    LT;
    LE;
    GT;
    GE;
    EQU;
    NEU;
    LTU;
    LEU;
    GTU;
    GEU;
    NAN;
    NUM;

//* FSET/HSET2
__DefBitFieldType BVal<1>
    //* Boolean mask
    BM;
    //* Boolean float
    BF;

__DefBitFieldType IFmt<3>
    S8;
    U8;
    S16;
    U16;
    S32;
    U32;
    S64;
    U64;

__DefBitFieldType FFmt<2>
    F32;
    F16;
    BF16;

__DefBitFieldType FRNDMode<2>
    ROUND;
    CEIL;
    FLOOR;
    TRUNC;

__DefBitFieldType RndRNRZ<1>
    RN;
    RZ;

__DefBitFieldType IPackFmt<1>
    I4;
    I2;

__DefBitFieldType WrSB<3>
    WSB0 = 0x0;
    WSB1;
    WSB2;
    WSB3;
    WSB4;
    WSB5;
    WSBInvalid; //
    WSBNone;

__DefBitFieldType Sched<5>
    W0;
    W1;
    W2;
    W3;
    W4;
    W5;
    W6;
    W7;
    W8;
    W9;
    W10;
    W11;
    W12;
    W13;
    W14;
    W15;
    W0Y;
    W1Y;
    W2Y;
    W3Y;
    W4Y;
    W5Y;
    W6Y;
    W7Y;
    W8Y;
    W9Y;
    W10Y;
    W11Y;
    W12Y;
    W13Y;
    W14Y;
    W15Y;
    //...

__DefBitFieldType Trap<1>
    NoTrap = 0x0;
    Trap = 0x1;

// Special Imm Type, need special treatment for assignment
// ":" in <> means it's a group of types, should be split into a set of types
// such as UImm1, UImm2, ..., UImm127
__DefImmBitFieldType UImm<1:128>;
__DefImmBitFieldType SImm<2:128>;
__DefImmBitFieldType F16Imm<16>;
__DefImmBitFieldType CMem<22>;
__DefImmBitFieldType BF16Imm<16>;
__DefImmBitFieldType F32Imm<32>;
__DefImmBitFieldType F16ImmX2<32>;
__DefImmBitFieldType BF16ImmX2<32>;
__DefImmBitFieldType F64Imm<32>;
__DefImmBitFieldType ReqSB<6>;

// __DefPropType 主要是定义一些其他辅助类型，与指令编码无关，但可能与解码有关
__DefPropType PipeType<4>
    FALU_Pipe;
    IALU_Pipe;
    SFU_Pipe;
    LSU_Pipe;
    BRU_Pipe;
    IB_Pipe;
    // ...

// define exception types
__DefPropType EncodingErrorType<8>
    IllegalOpcode;
    IllegalBitFieldValue;
    IllegalBitFieldCombination;
    OutOfRangeGPRIndex;
    UnalignedGPRIndex;
    UnalignedUGPRIndex;
    UnalignedCMemImmediate;
    IllegalWriteSB;
    IllegalSchedule;

__DefPropType RuntimeExceptionType<8>
    IllegalPC;
    IllegalBRUState;
    InvalidBARCount;
    InconsistentBARMode;
    InconsistentBARCount;
    InvalidWARPSYNCMemberMask;
    InvalidRTTState;
    InvalidTRAPIndex;
    InvalidSYSCALLState;
    IllegalMemoryAddress;
    UnalignedMemoryAddress;
    InvalidConstBank;
    InvalidGPRIndex;
    InvalidUGPRIndex;
    InvalidHWRegisterIndex;
    InvalidSWITCHState;
